/*
 * Copyright (C) 2009 M. Hautle.
 * 
 * This file is part of TrackedBean.
 * 
 * TrackedBean is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General
 * Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
 * later version.
 * 
 * TrackedBean is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Lesser General Public License along with TrackedBean. If not, see
 * <http://www.gnu.org/licenses/>.
 */
package ch.trackedbean.loaders.lazy;

import java.util.*;
import ch.trackedbean.common.*;

/**
 * Manager for {@link ILazyLoader}s.
 * 
 * @author M. Hautle
 */
public final class LazyLoaderManager {
	/** Map holding the loaders. */
	private static Map<Class<?>, ILazyLoader> loaders = new HashMap<Class<?>, ILazyLoader>();

	/** The default loader (used if no specific loader was found) */
	private static ILazyLoader defaultLoader;

	/** The {@link IExceptionHandler} of this manager. */
	private static IExceptionHandler exceptionHandler = new DefaultExceptionHandler(LazyLoaderManager.class);

	/**
	 * Default constructor.
	 */
	private LazyLoaderManager() {
	}

	/**
	 * Loads the value of the given property.
	 * 
	 * @param <T> The type of the declaring class
	 * @param declaringClass The declaring class
	 * @param bean The concerned bean
	 * @param property The property to load
	 * @return The value of the property.
	 * @throws NoLoaderException If no loader was found
	 */
	public static <T> Object loadProperty(Class<T> declaringClass, T bean, String property) throws NoLoaderException {
		try {
			ILazyLoader loader = loaders.get(declaringClass);
			if (loader == null)
				loader = defaultLoader;
			if (loader == null)
				throw new NoLoaderException(declaringClass);
			return loader.loadProperty(declaringClass, bean, property);
		} catch (Exception e) {
			exceptionHandler.exceptionOccourd(e);
			return null;
		}
	}

	/**
	 * Registers a loader for a given class.
	 * 
	 * @param declaringClass The class for which the loader gets registred
	 * @param loader The loader to use
	 */
	public static void registerLoader(Class<?> declaringClass, ILazyLoader loader) {
		loaders.put(declaringClass, loader);
	}

	/**
	 * Unregisters the loader for the given class.
	 * 
	 * @param declaringClass The concerned class
	 * @return The removed loader
	 */
	public static ILazyLoader unregisterLoader(Class<?> declaringClass) {
		return loaders.remove(declaringClass);
	}

	/**
	 * @return Returns the defaultLoader.
	 */
	public static ILazyLoader getDefaultLoader() {
		return defaultLoader;
	}

	/**
	 * @param defaultLoader The defaultLoader to set.
	 */
	public static void setDefaultLoader(ILazyLoader defaultLoader) {
		LazyLoaderManager.defaultLoader = defaultLoader;
	}

	/**
	 * Sets the {@link IExceptionHandler} of the manager.
	 * 
	 * @param handler The handler
	 */
	public static void setExceptionHandler(IExceptionHandler handler) {
		if (handler == null)
			throw new IllegalArgumentException("Null is not allowed!");
		exceptionHandler = handler;
	}
}
